import type { UploadFile } from 'antd';

/**
 * 文件类型映射
 */
export const FILE_TYPES = {
  IMAGE: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'],
  DOCUMENT: [
    'application/pdf',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  ],
  ARCHIVE: ['application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed'],
} as const;

/**
 * 常用文件类型组合
 */
export const COMMON_ACCEPTS = {
  // 证件类文件
  CERTIFICATE: [...FILE_TYPES.IMAGE, 'application/pdf'],
  // 办公文档
  OFFICE: [...FILE_TYPES.DOCUMENT],
  // 图片
  IMAGE_ONLY: FILE_TYPES.IMAGE,
  // 所有支持的类型
  ALL: [...FILE_TYPES.IMAGE, ...FILE_TYPES.DOCUMENT, ...FILE_TYPES.ARCHIVE],
} as const;

/**
 * 获取文件扩展名
 */
export const getFileExtension = (filename: string): string => {
  return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);
};

/**
 * 根据文件类型获取图标
 */
export const getFileIcon = (file: UploadFile): string => {
  const type = file.type || '';
  const extension = getFileExtension(file.name || '').toLowerCase();

  if (type.startsWith('image/')) {
    return '🖼️';
  }

  if (type === 'application/pdf' || extension === 'pdf') {
    return '📄';
  }

  if (type.includes('word') || ['doc', 'docx'].includes(extension)) {
    return '📝';
  }

  if (type.includes('excel') || ['xls', 'xlsx'].includes(extension)) {
    return '📊';
  }

  if (type.includes('powerpoint') || ['ppt', 'pptx'].includes(extension)) {
    return '📺';
  }

  if (type.includes('zip') || ['zip', 'rar', '7z'].includes(extension)) {
    return '🗜️';
  }

  return '📎';
};

/**
 * 格式化文件大小
 */
export const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B';

  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

/**
 * 验证文件类型
 */
export const validateFileType = (file: File, allowedTypes: string[]): boolean => {
  return allowedTypes.includes(file.type);
};

/**
 * 验证文件大小
 */
export const validateFileSize = (file: File, maxSizeMB: number): boolean => {
  const maxSizeBytes = maxSizeMB * 1024 * 1024;
  return file.size <= maxSizeBytes;
};

/**
 * 将文件转换为base64
 */
export const fileToBase64 = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = error => reject(error);
  });
};

/**
 * 压缩图片
 */
export const compressImage = (
  file: File,
  maxWidth: number = 1920,
  maxHeight: number = 1080,
  quality: number = 0.8
): Promise<File> => {
  return new Promise((resolve, reject) => {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const img = new Image();

    img.onload = () => {
      // 计算压缩后的尺寸
      let { width, height } = img;

      if (width > maxWidth || height > maxHeight) {
        const ratio = Math.min(maxWidth / width, maxHeight / height);
        width *= ratio;
        height *= ratio;
      }

      canvas.width = width;
      canvas.height = height;

      // 绘制压缩后的图片
      ctx?.drawImage(img, 0, 0, width, height);

      canvas.toBlob(
        blob => {
          if (blob) {
            const compressedFile = new File([blob], file.name, {
              type: file.type,
              lastModified: Date.now(),
            });
            resolve(compressedFile);
          } else {
            reject(new Error('图片压缩失败'));
          }
        },
        file.type,
        quality
      );
    };

    img.onerror = () => reject(new Error('图片加载失败'));
    img.src = URL.createObjectURL(file);
  });
};

/**
 * 提取上传成功的文件URL列表
 */
export const extractFileUrls = (fileList: UploadFile[]): string[] => {
  return fileList
    .filter(file => file.status === 'done' && file.response?.url)
    .map(file => file.response.url);
};

/**
 * 将URL转换为UploadFile格式
 */
export const urlsToUploadFiles = (urls: string[]): UploadFile[] => {
  return urls.map((url, index) => ({
    uid: `${index}`,
    name: url.split('/').pop() ?? `file-${index}`,
    status: 'done',
    url,
  }));
};

/**
 * 自定义上传请求
 */
export const customRequest = async options => {
  const { file, onSuccess, onError, onProgress } = options;

  const formData = new FormData();
  formData.append('file', file);

  try {
    const xhr = new XMLHttpRequest();

    // 上传进度
    xhr.upload.addEventListener('progress', event => {
      if (event.lengthComputable) {
        const percent = Math.round((event.loaded / event.total) * 100);
        onProgress({ percent });
      }
    });

    // 上传完成
    xhr.addEventListener('load', () => {
      if (xhr.status === 200) {
        const response = JSON.parse(xhr.responseText);
        onSuccess(response);
      } else {
        onError(new Error('上传失败'));
      }
    });

    // 上传错误
    xhr.addEventListener('error', () => {
      onError(new Error('上传失败'));
    });

    xhr.open('POST', '/api/upload');
    xhr.send(formData);
  } catch (error) {
    onError(error);
  }
};

/**
 * 预设的上传配置
 */
export const UPLOAD_PRESETS = {
  // 证件上传
  CERTIFICATE: {
    acceptTypes: COMMON_ACCEPTS.CERTIFICATE,
    maxCount: 2,
    maxSize: 5,
    listType: 'picture-card' as const,
    placeholder: '支持JPG、PNG、PDF格式，最多2个文件，单个文件不超过5MB',
  },

  // 头像上传
  AVATAR: {
    acceptTypes: FILE_TYPES.IMAGE,
    maxCount: 1,
    maxSize: 2,
    listType: 'picture-circle' as const,
    placeholder: '支持JPG、PNG格式，文件大小不超过2MB',
  },

  // 文档上传
  DOCUMENT: {
    acceptTypes: COMMON_ACCEPTS.OFFICE,
    maxCount: 10,
    maxSize: 20,
    listType: 'text' as const,
    placeholder: '支持PDF、Word、Excel格式，最多10个文件',
  },

  // 图片相册
  GALLERY: {
    acceptTypes: FILE_TYPES.IMAGE,
    maxCount: 9,
    maxSize: 10,
    listType: 'picture-card' as const,
    placeholder: '支持JPG、PNG格式，最多9张图片',
  },
} as const;
